package scene;

import java.util.ArrayList;

import javax.vecmath.Color3f;

import object.SceneObject;

import light.AmbientLight;
import light.PointLight;

import ray.Ray;
import ray_tracer.Camera;

import util.Point3D;

public class Scene {

	private static Scene instance = null;

	private ArrayList<SceneObject> objects;
	private ArrayList<PointLight> pointLights;
	private AmbientLight ambientLight;
	private Color3f backgroundColor;
	private Camera camera;

	private Scene() {
		this.objects = new ArrayList<SceneObject>();
		this.pointLights = new ArrayList<PointLight>();
		this.camera = new Camera();
		this.backgroundColor = new Color3f(0.5f, 0.5f, 0.8f);
	}

	public static Scene getInstance() {
		if (instance == null) {
			instance = new Scene();
		}
		return instance;
	}

	public Color3f getBackgroundColor() {
		return backgroundColor;
	}

	public Camera getCamera() {
		return camera;
	}

	public void addSceneObject(SceneObject newObject) {
		this.objects.add(newObject);
	}

	public ArrayList<PointLight> getPointLights() {
		return pointLights;
	}

	public void addPointLight(PointLight pointLight) {
		this.pointLights.add(pointLight);
	}

	public AmbientLight getAmbientLight() {
		return ambientLight;
	}

	public void setAmbientLight(AmbientLight ambientLight) {
		this.ambientLight = ambientLight;
	}

	public IntersectionInfo getClosestIntersection(Ray r) {
		ArrayList<IntersectionInfo> intersections = new ArrayList<IntersectionInfo>();
		Point3D intersect;
		for (SceneObject o : objects) {
			intersect = o.getClosestIntersectionPoint(r);
			if (intersect != null) {
				intersections.add(new IntersectionInfo(o, intersect, o
						.getNormalAtPoint(intersect)));
			}
		}

		if (intersections.isEmpty()) {
			return null;
		} else {
			float closestDistance = Float.MAX_VALUE;
			IntersectionInfo closestIntersection = intersections.get(0);
			for (IntersectionInfo i : intersections) {
				float distance = i.getPoint().distanceTo(r.getOrigin());
				if (distance < closestDistance) {
					closestDistance = distance;
					closestIntersection = i;
				}
			}
			
			return closestIntersection;
		}
	}

}
